# -*- coding: utf-8 -*-
import sys
from PySide import QtGui
from PySide import QtCore
from PySide import QtNetwork


class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.init_ui()
        self.init_data()
        self.init_socket()

    def __del__(self):
        if not self.server:
            self.client_list.clear()
            self.server.close()

    def init_ui(self):
        self.setWindowTitle(u'服务器')
        self.info = QtGui.QTextEdit()
        self.info.setReadOnly(True)
        self.send_text = QtGui.QTextEdit()
        self.btn = QtGui.QPushButton(u'发送所有')
        self.btn.clicked.connect(self.send_all)
        self.client_box = QtGui.QListWidget()

        left_splitter = QtGui.QSplitter(QtCore.Qt.Vertical)
        left_splitter.addWidget(self.info)
        left_splitter.addWidget(self.send_text)
        left_splitter.addWidget(self.btn)
        left_splitter.setStretchFactor(0, 3)
        left_splitter.setStretchFactor(1, 1)
        left_splitter.setStretchFactor(2, 1)

        main_splitter = QtGui.QSplitter(QtCore.Qt.Horizontal)
        main_splitter.addWidget(left_splitter)
        main_splitter.addWidget(self.client_box)
        main_splitter.setStretchFactor(0, 2)
        main_splitter.setStretchFactor(1, 1)

        main_layout = QtGui.QHBoxLayout()
        main_layout.addWidget(main_splitter)
        self.setLayout(main_layout)

    def init_data(self):
        self.client_list = []
        self.server = None

    def init_socket(self):
        self.server = QtNetwork.QTcpServer()
        self.server.listen(QtNetwork.QHostAddress.Any, 60000)
        self.server.newConnection.connect(self.connect)

    def connect(self):
        client = self.server.nextPendingConnection()
        client.readyRead.connect(self.recv)
        client.disconnected.connect(self.disconnected)
        self.client_list.append(client)
        self.update_client_box()
        client_str = u'欢迎[%s:%d]加入' % (client.peerAddress().toString(), client.peerPort())
        self.send_all_without(client, client_str)
        self.info.append(client_str)

    def recv(self):
        client = self.sender()
        recv_buf = client.readAll().data().decode('utf-8')
        buf = u'[%s:%d]说: %s' % (client.peerAddress().toString(), client.peerPort(), recv_buf)
        self.info.append(buf)
        self.send_all_without(client, buf)

    def disconnected(self):
        if self.sender() in self.client_list:
            self.client_list.remove(self.sender())
            self.update_client_box()
            buf = u'[%s:%d]离开了' % (self.sender().peerAddress().toString(), self.sender().peerPort())
            self.send_all_without(self.sender(), buf)
            self.info.append(buf)

    def send_all(self):
        self.boardcase(self.send_text.toPlainText())

    def send_all_without(self, socket, data):
        for clinet in self.client_list:
            if clinet != socket:
                clinet.write(data.encode('utf-8'))

    def boardcase(self, data):
        buf = u'[服务器消息]: %s' % data
        self.info.append(buf)
        for clinet in self.client_list:
            clinet.write(buf.encode('utf-8'))

    def update_client_box(self):
        self.client_box.clear()
        clients_str = map(lambda x: u'%s:%d' % (x.peerAddress().toString(), x.peerPort()), self.client_list)
        self.client_box.addItems(clients_str)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    widget = Window()
    widget.show()
    sys.exit(app.exec_())
